.model small

;
; imports
;


; void updatePedDispl(Position, Light, desetice, jedinice)
; extrn updatePedDispl

south equ 0
east equ 3
north equ 6
west equ 9
left equ 0
right equ 2
forward equ 1

red equ 00100b 
yellow equ 01110b
green equ 00010b
off equ 00111b ;sivo

public nextTimer
.data
	
	oldTimerSEG dw 0
	oldTimerOFF dw 0

	oldKeySEG dw 0
	oldKeyOFF dw 0
	
	simEnd dw 0
	
	semaphores db 12 dup (?)
	
		EastRight equ 2744d
		EastStr equ 2424d
		EastLeft equ 2104d
		
		WestRight equ 1184d
		WestStr equ 1504d
		WestLeft equ 1824d
		
		SouthRight equ 3098d
		SouthStr equ 3092d
		SouthLeft equ 3086d
		
		NorthLeft equ 840d
		NorthStr equ 834d
		NorthRight equ 828d
		
		coordinates dw SouthLeft, SouthStr,	SouthRight,	EastLeft, EastStr, EastRight, NorthLeft, NorthStr, NorthRight, WestLeft, WestStr, WestRight
		
	timeInitial dw 1 dup (1900d, 1900d, 1900d, 1900d, 1900d, 1900d, 1900d) ;sve racunice su u 10ms
	timeGainMax dw 700, 700, 0, 700, 700, 0;
	timeGain dw 1 dup (0, 0, 0, 0, 0, 0);
	timeCurrent dw 700	;for debug, FIX: ?
	timeMode db 0	;for debug, FIX:  (?) ; one of bellow
	VLR equ 0	; vertical left right
	VFR equ 2	; vertical forward right
	VF	equ 4	; vertical forward
	HLR equ 6	; vertical left right
	HFR equ 8	; vertical forward right
	HF	equ 10	; vertical forward
	YYY equ 12	; all yellow
	redTime equ 100; // ms
	yellowTime equ 100
	pedYellowTime equ 500
	
	
	arrivedFlag dw 0, 0
	crossingFlag dw 0, 0
	crossingTimeLeft dw 0, 0
	crossingLightColor dw off, off
	crossingDisplayColor dw off, off
	Horizontal equ 2
	Vertical equ 0
	timeTick equ 6
	
	simulator db "Simulacija saobracajne raskrsnice$"
		startSim db "s - startujte simulaciju$"
		pauseSim db "p - pauzirajte simulaciju $"
		addCar db "u - dodajte automobil$"
		endSim db "Esc - kraj simulacije.$"
		
		; koordinate za pozicije semafora automobila
		
		
		; koordinate i char za pozicije semafora peshaka
		
		Vert_1	equ 660d
		Vert_2 equ 704d
		Vert_3	equ 3220d
		Vert_4	equ 3264d
		VertLight equ 219 
		 
		Horiz_1	equ 816d
		Horiz_2	equ 868d
		Horiz_3	equ 3056d
		Horiz_4	equ 3108d
		HorizLight equ 219 
		
tickyStart equ 400
		tickyTick dw tickyStart
		
		; koordinate pozicije desetica i jedinica displeja za peshake
	
	VertDisp_jed1	equ 500d
	VertDisp_jed2 	equ 546d
	VertDisp_jed3	equ 3380d
	VertDisp_jed4	equ 3426d
	VertDisp_des1	equ 498d
	VertDisp_des2 	equ 544d
	VertDisp_des3	equ 3378d
	VertDisp_des4	equ 3424d
	HorizDisp_jed1	equ 812d
	HorizDisp_jed2	equ 874d
	HorizDisp_jed3	equ 3052d
	HorizDisp_jed4	equ 3114d	
	HorizDisp_des1	equ 810d
	HorizDisp_des2	equ 872d
	HorizDisp_des3	equ 3050d
	HorizDisp_des4	equ 3112d
	ASCIIadd equ 48 ;Koristi se za odredjivanje ASCII koda kada se prosledi cifra ->  0=ASCIIadd + 0   1 = ASCIIadd + 1 ... 9 = ASCIIadd + 9

.stack 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; code segment
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.code


;
; description:	macro for getting the argument passed through the stack
; parameters:	x	-	the order number from the top of the stack
;				reg	-	the register for saving the argument
;
getArg macro reg, x
mov reg, [bp + 4 + 2*x]
endm

;
; description:	macro for passing the return value on the stack
; parameter:	x	-	the order number from the top of the stack
;				reg	-	the register that holds the returning value
;
setArg macro reg, x
mov [bp + 4 + 2*x], reg
endm

firstLineType proc near
	push bp
	mov bp, sp

	push ax
	push bx
	push dx
	push di
	push es
	push cx
	
	mov ax, 0b800h
	mov es, ax	
	
	
	mov ah, 033h
	mov al, "" 
	
	
	getArg di 0
	
	mov cx, 12	
	cld 		
	rep stosw 	

		
	mov ah, 1111b
	mov al, 221
	
	mov cx, 1 
	cld 		
	rep stosw 	

	
	
	
	mov ah, 0000b
	mov al, ""
	
	mov cx, 2 	
	cld 		
	rep stosw 	

	

	
	mov ah, 1111b
	mov al, "|"
	
	mov cx, 1 	
	cld 		
	rep stosw 	

	
	mov ah, 0000b
	mov al, ""
	
	mov cx, 2 
	cld 		
	rep stosw 	
	
	
	
	mov ah, 1111b
	mov al, "|"
	
	mov cx, 1 
	cld 		
	rep stosw 	
	
	;mov es:byte ptr[di], al
	;mov es:byte ptr[di+1], ah
    
	mov ah, 0000b
	mov al, ""
	
	mov cx, 2 	; amount of times to put it there 
	cld 		; direction - forwards
	rep stosw 	; output character at ES:[DI]
	
	;mov es:byte ptr[di], al
	;mov es:byte ptr[di+1], ah

	 
	mov ah, 1111b
	mov al, 221

	mov cx, 1 	; amount of times to put it there 
	cld 		; direction - forwards
	rep stosw 	; output character at ES:[DI]
	
;	mov es:byte ptr[di], al
;	mov es:byte ptr[di+1], ah
	
	mov ah, 0000b
	mov al, ""
	
	;mov es:byte ptr[di], al
	;mov es:byte ptr[di+1], ah
	
	mov cx, 2 	; amount of times to put it there 
	cld 		; direction - forwards
	rep stosw 	; output character at ES:[DI]
	
	mov ah, 1111b
	mov al, "|"
	
	;mov es:byte ptr[di], al
	;mov es:byte ptr[di+1], ah
	
	mov cx, 1 	; amount of times to put it there 
	cld 		; direction - forwards
	rep stosw 	; output character at ES:[DI]
	
	mov ah, 0000b
	mov al, ""
	
	;mov es:byte ptr[di], al
	;mov es:byte ptr[di+1], ah
	
	mov cx, 2 	; amount of times to put it there 
	cld 		; direction - forwards
	rep stosw 	; output character at ES:[DI]
	
	mov ah, 1111b
	mov al, "|"
	
	mov cx, 1 	; amount of times to put it there 
	cld 		; direction - forwards
	rep stosw 	; output character at ES:[DI]
	
    
	mov ah, 0000b
	mov al, ""
	
	mov cx, 2 	
	cld 		; direction - forwards
	rep stosw 	; output character at ES:[DI]
	
	 
	mov ah, 1111b
	mov al, 222
	
	mov cx, 1 	
	cld 		
	rep stosw 	
	
	mov ah, 033h
	mov al, "" 	
	
	
	mov cx, 12 	
	cld 		
	rep stosw 	

	mov ah, 00h
	mov al, "" 	
	
	
	mov cx, 37 	
    cld 		
	rep stosw 	
	
	setArg di 0
	
	pop cx
	pop es
	pop di
	pop dx
	pop bx 
	pop ax
	pop bp
	ret  
firstLineType endp

secondLineType proc near
	push bp
	mov bp, sp

	push ax
	push bx
	push dx
	push di
	push es
	
	mov ax, 0b800h
	mov es, ax	; VIDEO mode
	
	getArg di 0
	
	mov ah, 1111b
	mov al, 223 	
	
	
	mov cx, 12 	 
	cld 		
	rep stosw 	
	
	
	mov ah, 00h
	mov al, "" 	
	
	
	mov cx, 19 	 
	cld 		
	rep stosw 	
	
	
	
	mov ah, 1111b
	mov al, 223 	
	
	
	mov cx, 12	 
	cld 		
	rep stosw 
	
		;add di, 37
	
	mov ah, 00h
	mov al, "" 	; character to put there
	
	
	mov cx, 37 	; amount of times to put it there 
    cld 		; direction - forwards
	rep stosw 	; output character at ES:[DI]

	
	setArg di 0
	
	pop es
	pop di
	pop dx
	pop bx 
	pop ax
	pop bp
	ret
secondLineType endp

thirdLineType proc near
	push bp
	mov bp, sp

	push ax
	push bx
	push dx
	push di
	push es
	
	mov ax, 0b800h
	mov es, ax	; VIDEO mode
	
	getArg di 0
	
;	add di, 80
	mov ah, 00h
	mov al, "" 	
	
	mov cx, 80	 
	cld 		
	rep stosw 	
	
	setArg di 0
	
	
	pop es
	pop di
	pop dx
	pop bx 
	pop ax
	pop bp
	ret
thirdLineType endp

fourthLineType proc near
	push bp
	mov bp, sp

	push ax
	push bx
	push dx
	push di
	push es
	
	mov ax, 0b800h
	mov es, ax	; VIDEO mode
	
	getArg di 0
	
	mov ah, 1111b
	mov al, "-" 	
	
	
	mov cx, 12 	 
	cld 		
	rep stosw 	
	
	
	mov ah, 00h
	mov al, "" 	
	
	
	mov cx, 19 	 
	cld 		
	rep stosw 	
	
	
	
	mov ah, 1111b
	mov al, "-" 	
	
	
	mov cx, 12	 
	cld 		
	rep stosw 
	
	
	
	mov ah, 00h
	mov al, "" 	; character to put there
	
	
	mov cx, 37 	; amount of times to put it there 
    cld 		; direction - forwards
	rep stosw 	; output character at ES:[DI]
	
	setArg di 0
	
	pop es
	pop di
	pop dx
	pop bx 
	pop ax
	pop bp
	ret
fourthLineType endp

fifthLineType proc near
	push bp
	mov bp, sp

	push ax
	push bx
	push dx
	push di
	push es
	
	mov ax, 0b800h
	mov es, ax	; VIDEO mode
	
	getArg di 0
	
	mov ah, 1111b
	mov al, 220 	
	
	
	mov cx, 12 	 
	cld 		
	rep stosw 	
	
	
	mov ah, 00h
	mov al, "" 	
	
	
	mov cx, 19 	 
	cld 		
	rep stosw 	
	
	
	
	mov ah, 1111b
	mov al, 220 	
	
	
	mov cx, 12	 
	cld 		
	rep stosw 
	
		;add di, 37
	
	mov ah, 00h
	mov al, "" 	; character to put there
	
	
	mov cx, 37 	; amount of times to put it there 
    cld 		; direction - forwards
	rep stosw 	; output character at ES:[DI]

	
	setArg di 0
	
	pop es
	pop di
	pop dx
	pop bx 
	pop ax
	pop bp
	ret
fifthLineType endp

setCursorPos proc near ; nije potrebna jer se vec postavi u di
	push ax
	push bx
	
	mov ah, 2
	mov bh, 0
	int 10h
	
	pop bx
	pop ax
	ret
setCursorPos endp

printString proc near
	push bp
	mov bp, sp
	
	push ax
	push es
	push bx
	push di
	push si
	push dx
	
	mov ax, 0b800h
	mov es, ax ; VIDEO MODE
	
	;mov ax, 2
	;int 10h
	
	getArg di 0 ; koordinate
	getArg bx, 1 ; pocetak stringa
	
	mov si, bx
	xor ax, ax
moreCha:
	mov al, [si]
	cmp ax, '$'
	je endString 
	mov es: byte ptr [di], al
	mov es: byte ptr [di+1], 1111b
	inc si
	inc di
	inc di
	jmp moreCha
	
endString:	
	pop dx 
	pop si
	pop di
	pop bx
	pop es
	pop ax
	pop bp
	ret
printString endp

drawCrossRoad proc near
	push bp
	mov bp, sp
	
	push ax
	push es
	push di
	push cx
	
	mov ax, 0b800h
	mov es, ax ; VIDEO MODE

	xor di,di 
	
	
	mov cx, 6
top:
	push di
	call firstLineType
	pop di
	loop top
	
	push di
	call secondLineType
	pop di
	
	push di
	call thirdLineType
	pop di

	push di
	call fourthLineType
	pop di
	
	push di
	call thirdLineType
	pop di

	push di
	call fourthLineType
	pop di
	
	push di
	call thirdLineType
	pop di
	
	
	push di
	call fifthLineType
	pop di
	
	push di
	call thirdLineType
	pop di

	push di
	call fourthLineType
	pop di
	
	push di
	call thirdLineType
	pop di

	push di
	call fourthLineType
	pop di
	
	push di
	call thirdLineType
	pop di
	
	push di
	call fifthLineType
	pop di
	
	mov cx, 6
bottom:
		push di
		call firstLineType
		pop di
		loop bottom
	
		 
	lea bx, simulator
	mov di, 250d
	push bx
	push di
	call printString
	
	lea bx, startSim
	mov di, 570d
	push bx
	push di
	call printString
	
	lea bx, addCar
	mov di, 730d
	push bx
	push di
	call printString
	
	lea bx, endSim
	mov di, 890d
	push bx
	push di
	call printString

	;inicialno dodavanje semafora za automobile. svi crveni.
	mov di, EastRight
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
	
	mov di, EastStr
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
	
	mov di, EastLeft
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
		
	mov di, WestRight
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
	
	mov di, WestStr
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
	
	mov di, WestLeft
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
	
	mov di, SouthRight
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
	
	mov di, SouthStr
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
	
	mov di, SouthLeft
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
	
	mov di, NorthRight
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
	
	mov di, NorthStr
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
	
	mov di, NorthLeft
	mov es: byte ptr [di], 254
	mov es: byte ptr [di+1], 04h
	
	;inicijalno postavljanje semafora za pesake. svi zeleni.
	
	mov di, Horiz_1
	mov es: byte ptr [di], HorizLight 
	mov es: byte ptr [di+1], green
	
	mov di, Horiz_2
	mov es: byte ptr [di], HorizLight
	mov es: byte ptr [di+1], green
	
	mov di, Horiz_3
	mov es: byte ptr [di], HorizLight
	mov es: byte ptr [di+1], green
	
	mov di, Horiz_4
	mov es: byte ptr [di], HorizLight
	mov es: byte ptr [di+1], green
	
	mov di, Vert_1
	mov es: byte ptr [di], VertLight
	mov es: byte ptr [di+1], green
	
	mov di, Vert_2
	mov es: byte ptr [di], VertLight
	mov es: byte ptr [di+1], green
	
	mov di, Vert_3
	mov es: byte ptr [di], VertLight
	mov es: byte ptr [di+1], green
	
	mov di, Vert_4
	mov es: byte ptr [di], VertLight
	mov es: byte ptr [di+1], green
	
	pop cx
	pop di
	pop es
	pop ax
	pop bp
	ret

drawCrossRoad endp



;----------------------------------------------------
; signature:	void updateSemaphore(index, Light)
;				>	Side		-	south, east, north, west (0, 1, 2, 3)
;				>	Order		-	left, foreward, right (0, 1, 2)
;				>	Light		-	light to set
; description:	sets the semaphore light
; comment:		the arguments are passed through the stack;
;				frees the arguments on the stack

updateSemaphore proc near
	push bp
	mov bp, sp
	
	pushf
	cli
	
	push ax
	push dx
	push di
	push bx
	
	mov ax, 0b800h
	mov es, ax ; VIDEO MODE

	getArg bx 0 ; index of the semaphore
	getArg ax 1 ; light
	
	
	mov di, bx
	lea bx, coordinates
	mov dx, [bx][di]
	mov di, dx
	  
	mov es: byte ptr[di], 254
	mov es: byte ptr[di+1], al
	
	
	pop bx
	pop di
	pop dx
	pop ax
	
	popf
	
	pop bp
	ret	4
updateSemaphore endp

;----------------------------------------------------
; signature:	void updatePedSemaphore(Position, Light)
;				>	Position		-	horizontal, vertical (0, 1)
;				>	Light		-	light to set
; description:	sets the pedestrian semaphore light
; comment:		the arguments are passed through the stack;
;				frees the arguments on the stack
updatePedSemaphore proc near
	push bp
	mov bp, sp
	
	pushf
	cli
	
	push es
	push ax
	push dx
	push di
	push bx
	
	mov ax, 0b800h
	mov es, ax ; VIDEO MODE

	getArg ax 0 ; position
	mov dx, ax
	getArg bx 1 ; light

	xor ax, ax
	mov al, bl  
dissem:	
	cmp dx, Horizontal
	je Hor
	cmp dx, Vertical
	je Ver
	
Hor:
	mov di, Horiz_1
	mov es: byte ptr [di], HorizLight 
	mov es: byte ptr [di+1], al
	
	mov di, Horiz_2
	mov es: byte ptr [di], HorizLight
	mov es: byte ptr [di+1], al
	
	mov di, Horiz_3
	mov es: byte ptr [di], HorizLight
	mov es: byte ptr [di+1], al
	
	mov di, Horiz_4
	mov es: byte ptr [di], HorizLight
	mov es: byte ptr [di+1], al
	jmp end_setps

Ver:
	mov di, Vert_1
	mov es: byte ptr [di], VertLight
	mov es: byte ptr [di+1], al
	
	mov di, Vert_2
	mov es: byte ptr [di], VertLight
	mov es: byte ptr [di+1], al
	
	mov di, Vert_3
	mov es: byte ptr [di], VertLight
	mov es: byte ptr [di+1], al
	
	mov di, Vert_4
	mov es: byte ptr [di], VertLight
	mov es: byte ptr [di+1], al

end_setps:
		pop bx
		pop di
		pop dx
		pop ax
		pop es
		
		popf 
		
		pop bp
		ret	4
	
updatePedSemaphore endp

;------------------------------------------------
;  void updatePedDispl(Position, Light, desetice, jedinice)
;				>	Position		-	horizontal, vertical (0, 1)
;				>	Light		-	light to set
;				>	desetice
;				>	jedinice
; description:	sets the pedestrian count display and light of display
; comment:		the arguments are passed through the stack;
;				frees the arguments on the stack
updatePedDispl proc near
	push bp
	mov bp, sp

	pushf
	cli
	
	push es
	push ax
	push dx
	push di
	push bx
	push cx

	mov ax, 0b800h
	mov es, ax ; VIDEO MODE
	
	xor dx, dx
	xor al, al
	
	getArg dx 0 ; Position
	getArg ax 1 ; light
	
	getArg bx 2 ; desetice
	getArg cx 3 ; jedinice
	
	add bx, ASCIIadd ; ascii kod za desetice
	add cx, ASCIIadd ; ascii kod za jedinice
	
	cmp dx, Horizontal
	je Horr
	cmp dx, Vertical
	je Verrt
	Horr:
	
	mov di, HorizDisp_jed1
	mov es: byte ptr [di], cl
	mov es: byte ptr [di+1], al
	
	mov di, HorizDisp_jed2
	mov es: byte ptr [di], cl
	mov es: byte ptr [di+1], al
	
	mov di, HorizDisp_jed3
	mov es: byte ptr [di], cl
	mov es: byte ptr [di+1], al
	
	mov di, HorizDisp_jed4
	mov es: byte ptr [di], cl
	mov es: byte ptr [di+1], al
	
	
	mov di, HorizDisp_des1
	mov es: byte ptr [di], bl
	mov es: byte ptr [di+1], al
	
	mov di, HorizDisp_des2
	mov es: byte ptr [di], bl
	mov es: byte ptr [di+1], al
	
	mov di, HorizDisp_des3
	mov es: byte ptr [di], bl
	mov es: byte ptr [di+1], al
	
	mov di, HorizDisp_des4
	mov es: byte ptr [di], bl
	mov es: byte ptr [di+1], al
	jmp endpds
	
	
	
	Verrt:
	mov di, VertDisp_jed1
	mov es: byte ptr [di], cl
	mov es: byte ptr [di+1], al
	
	mov di, VertDisp_jed2
	mov es: byte ptr [di], cl
	mov es: byte ptr [di+1], al
		
	mov di, VertDisp_jed3
	mov es: byte ptr [di], cl
	mov es: byte ptr [di+1], al
	
	mov di, VertDisp_jed4
	mov es: byte ptr [di], cl
	mov es: byte ptr [di+1], al
	
	
	mov di, VertDisp_des1
	mov es: byte ptr [di], bl
	mov es: byte ptr [di+1], al
	
	mov di, VertDisp_des2
	mov es: byte ptr [di], bl
	mov es: byte ptr [di+1], al
	
	mov di, VertDisp_des3
	mov es: byte ptr [di], bl
	mov es: byte ptr [di+1], al
	
	mov di, VertDisp_des4
	mov es: byte ptr [di], bl
	mov es: byte ptr [di+1], al
	
	endpds:
	pop cx
	pop bx
	pop di
	pop dx
	pop ax
	pop es
	
	popf
	
	pop bp
	ret 8
	
updatePedDispl endp

;--------------------------------------------------
;	calculates the light of the semaphore for vehicles
;	Light calcLight(void)
;	example of usage:
;		sub sp, 2
;		call calcLight
;		pop ax
calcLight proc near
	push bp
	mov bp, sp

	push ax
	push dx
	
	mov ax, timeCurrent
	sub ax, redTime
	cmp ax, 0
	jng calcLight_red
	cmp ax, yellowTime
	jng calcLight_yellow
	cmp ax, yellowTime + 50
	jng	calcLight_green
	cmp ax, yellowTime +  100
	jng	calcLight_off
	cmp ax, yellowTime +  150
	jng	calcLight_green
	cmp ax, yellowTime +  200
	jng	calcLight_off
	cmp ax, yellowTime +  250
	jng	calcLight_green
	cmp ax, yellowTime +  300
	jng	calcLight_off
	
	sub sp, 2
	call initialTime
	pop dx
	mov ax, timeCurrent
	sub dx, redTime
	cmp ax, dx
	jnl calcLight_red
	sub dx, yellowTime
	cmp ax, dx
	jnl calcLight_yellow
calcLight_green:
	mov dx, green
	jmp calcLight_ret
calcLight_yellow:
	mov dx, yellow
	jmp calcLight_ret
calcLight_off:
	mov dx, off
	jmp calcLight_ret
calcLight_red:
	mov dx, red
	
calcLight_ret:
	setArg dx, 0
	
	pop dx
	pop ax
	pop bp
	ret
calcLight endp
;--------------------------------------------------

;
;	push horizontal/vertical
;	call calcPedLight
;	pop reg	
;
calcPedLight proc
	push bp
	mov bp, sp

	push ax
	push bx
	push di
	push dx
	
	xor dx, dx
	lea bx, crossingFlag
	getArg di 0
	mov ax, [bx][di]
	cmp ax, 1
	je calcPedLight_cross
	mov ax, red
	jmp calcPedLight_end
calcPedLight_cross:
	lea bx, crossingTimeLeft
	mov ax, [bx][di]
	cmp ax, pedYellowTime
	jl calcPedLight_blink
	mov ax, green
	jmp calcPedLight_end
calcPedLight_blink:
	mov bx, 70d
	div bx
	and ax, 01h
	cmp ax, 0
	je calcPedLight_even
	mov ax, off
	jmp calcPedLight_end
calcPedLight_even:
	mov ax, green
calcPedLight_end:
	setArg ax 0
	
	pop dx
	pop di
	pop bx
	pop ax
	
	pop bp
	ret
calcPedLight endp

;
;	push horizontal/vertical
;	call calcPedLight
;	pop reg
;
calcPedDispLight proc
	push bp
	mov bp, sp

	push ax
	push bx
	push di
	
	lea bx, crossingFlag
	getArg di 0
	mov ax, [bx][di]
	cmp ax, 1
	je calcPedDispLight_cross
	xor ax, ax
	mov al, red
	jmp calcPedDispLight_end
calcPedDispLight_cross:
	lea bx, crossingTimeLeft
	mov ax, [bx][di]
	cmp ax, pedYellowTime
	jl calcPedDispLight_yellow
	xor ax, ax
	mov al, green
	jmp calcPedDispLight_end
calcPedDispLight_yellow:
	xor ax, ax
	mov al, yellow
calcPedDispLight_end:
	setArg ax 0
	
	pop di
	pop bx
	pop ax
	
	pop bp
	ret
calcPedDispLight endp


;--------------------------------------------------
;   returns time that iteraton time length differs 
;           from the initial one
;	signature: long timeGained( direction )
;						direction: VLR||VFR||...||HF
;
;	push arg
;	call timeGained
;	pop reg
;
;--------------------------------------------------
timeGained proc near
	push bp
	mov bp, sp
	push ax
	push bx
	push di
	
	getArg ax 0
	mov di, ax
	lea bx, timeGain
	
	cmp ax, VF
	jne timeGained_HF
	mov ax, [bx][VLR]
	add ax, [bx][VFR]
	jmp timeGainedRet
timeGained_HF:
	cmp ax, HF
	jne timeGained_else
	mov ax, [bx][HLR]
	add ax, [bx][HFR]
	jmp timeGainedRet
timeGained_else:
	mov ax, [bx][di]
	xor bx, bx ; TODO negacija u komplementu dvojke?
	sub bx, ax
	mov ax, bx
timeGainedRet:	
	setArg ax 0
	pop di
	pop bx
	pop ax
	pop bp
	ret
timeGained endp

;----------------------------------------------
;	call:
;	sub sp, 2
;	call nextTimer
;	pop ax
;	
nextTimer proc near
	push bp
	mov bp, sp
	
	push ax
	push bx
	xor ax, ax
	mov al, byte ptr timeMode
	add ax, 2
	mov bl, 12
	div bl
	xor bx, bx
	mov bl, ah
	
	setArg bx 0
	
	pop bx
	pop ax
	pop bp ; next timer
	ret
nextTimer endp
;----------------------------------------------

changeState proc near
	xor dx, dx
	mov dl, timeMode
	cmp dx, VF
	je changeState_VF_reset
	cmp dx, HF
	je changeState_HF_reset
	jmp changeState_next_state
changeState_VF_reset:
	lea bx, arrivedFlag
	mov word ptr [bx + Horizontal], 0
	lea bx, timeGain
	mov word ptr [bx + VFR], 0
	mov word ptr [bx + VLR], 0
	mov word ptr [bx + VF], 0
	jmp changeState_next_state
changeState_HF_reset:
	lea bx, arrivedFlag
	mov word ptr [bx + Vertical], 0
	lea bx, timeGain
	mov word ptr [bx + HFR], 0
	mov word ptr [bx + HLR], 0
	mov word ptr [bx + HF], 0
changeState_next_state:
	sub sp, 2
	call nextTimer
	pop di
	
	xor dx, dx
	cmp di, VLR
	je changeState_New_VLR_VFR
	cmp di, VFR
	je changeState_New_VLR_VFR
	cmp di, VF
	je changeState_New_VF
	cmp di, HLR
	je changeState_New_HLR_HFR
	cmp di, HFR
	je changeState_New_HLR_HFR
	cmp di, HF
	je changeState_New_HF
	
changeState_New_VLR_VFR:
	lea bx, arrivedFlag
	mov dx, [bx][Horizontal]
	cmp dx, 1
	jne changeState_ret
	lea bx, timeGainMax
	mov dx, [bx][di]
	lea bx, timeGain
	mov [bx][di], dx
	jmp changeState_ret

changeState_New_VF:
	lea bx, arrivedFlag
	mov dx, [bx][Horizontal]
	cmp dx, 1
	jne changeState_ret
	xor dx, dx
	lea bx, timeGain
	sub dx, [bx][VLR]
	sub dx, [bx][VFR]
	jmp changeState_ret

changeState_New_HLR_HFR:
	lea bx, arrivedFlag
	mov dx, [bx][Vertical]
	cmp dx, 1
	jne changeState_ret
	lea bx, timeGainMax
	mov dx, [bx][di]
	lea bx, timeGain
	mov [bx][di], dx
	jmp changeState_ret

changeState_New_HF:
	lea bx, arrivedFlag
	mov dx, [bx][Vertical]
	cmp dx, 1
	jne changeState_ret
	xor dx, dx
	lea bx, timeGain
	sub dx, [bx][HLR]
	sub dx, [bx][HFR]
	
changeState_ret:
	lea bx, timeInitial
	mov ax, [bx][di]
	sub ax, dx
	mov timeCurrent, ax
	
	mov ax, di
	mov timeMode, al
	ret
changeState endp

;------------------------------------------------
;	long initialTime(void)
;
;	calling (ax <- initialTime):
;	sub sp, 2
;	call initialTime
;	pop ax
;------------------------------------------------
initialTime proc near
	push bp
	mov bp, sp
	
	push ax
	push bx
	push dx
	push di
	
	xor ax, ax
	mov al, timeMode
	push ax
	call timeGained
	pop dx
	
	lea bx, timeInitial
	mov di, ax
	mov ax, [bx][di]
	add ax, dx
	
	setArg ax 0
	pop di
	pop dx
	pop bx
	pop ax
	
	pop bp
	ret
initialTime endp

isInitialPhase proc near
	push bp
	mov bp, sp
	push ax
	push dx
	
	sub sp, 2
	call initialTime
	pop dx
	sub dx, redTime
	sub dx, yellowTime
	
	mov ax, timeCurrent
	
	cmp ax, dx
	jge isInitialPhaseYes
	mov ax, 0
	jmp isInitialPhaseEnd
isInitialPhaseYes:
	mov ax, 1
isInitialPhaseEnd:
	setArg ax 0
	
	pop dx
	pop ax
	pop bp
	ret
isInitialPhase endp

isFinalPhase proc near
	push bp
	mov bp, sp
	
	push ax
	push dx
	
	mov dx, timeCurrent
	xor ax, ax
	add ax, redTime
	add ax, yellowTime
	add ax, 300 ;blinking
	
	cmp dx, ax
	jng isFinalPhaseYes
	mov ax, 0
	jmp isFinalPhaseEnd
isFinalPhaseYes:
	mov ax, 1
isFinalPhaseEnd:
	setArg ax 0
	
	pop dx
	pop ax
	pop bp
	ret
isFinalPhase endp

tickVLR proc near
	mov di, 2 * (south + left)
	push dx
	push di
	call updateSemaphore

	mov di, 2 * (north + left)
	push dx
	push di
	call updateSemaphore
	
	sub sp, 2
	call isFinalPhase
	pop cx
	cmp cx, 0 ;if no
	je tickVLR_notFinal
	xor dx, dx
	mov dl, green
	
tickVLR_notFinal:	
	mov di, 2 * (south + right)
	push dx
	push di
	call updateSemaphore
	
	mov di, 2 * (north + right)
	push dx
	push di
	call updateSemaphore
;
;void updateSemaphore(Side, Order, Light)
	
	
	mov ax, timeCurrent
	lea bx, timeInitial
	add ax, redTime
	add ax, [bx][VFR]
	lea bx, arrivedFlag
	mov cx, [bx][Horizontal]
	cmp cx, 0
	je tick_VLR_H_n_arr
	lea bx, timeGainMax
	mov cx, [bx][VFR]
	sub ax, cx
tick_VLR_H_n_arr:
	lea bx, crossingFlag
	mov word ptr [bx + Horizontal], 0
	lea bx, crossingTimeLeft
	mov [bx][Horizontal], ax
	
	mov ax, timeCurrent
	lea bx, timeInitial
	add ax, redTime
	add ax, [bx][VFR]
	add ax, [bx][VF]
	add ax, [bx][HLR]
	add ax, [bx][HFR]
	mov cx, VLR
	push cx
	call timeGained
	pop cx
	sub ax, cx
	lea bx, arrivedFlag
	mov cx, [bx][Vertical]
	cmp cx, 0
	je tick_VLR_V_n_arr
	lea bx, timeGainMax
	mov cx, [bx][HLR]
	sub ax, cx
	mov cx, [bx][HFR]
	sub ax, cx
tick_VLR_V_n_arr:
	lea bx, crossingFlag
	mov word ptr [bx + Vertical], 0
	lea bx, crossingTimeLeft
	mov [bx][Vertical], ax
	
	ret
tickVLR endp

tickHLR proc near
	mov di, 2 * (west + left)
	push dx
	push di
	call updateSemaphore

	mov di, 2 * (east + left)
	push dx
	push di
	call updateSemaphore
	
	sub sp, 2
	call isFinalPhase
	pop cx
	cmp cx, 0 ;if yes
	je tickHLR_notFinal
	mov dx, green
	
tickHLR_notFinal:	
	mov di, 2 * (west + right)
	push dx
	push di
	call updateSemaphore
	
	mov di, 2 * (east + right)
	push dx
	push di
	call updateSemaphore
;
;void updateSemaphore(Side, Order, Light)
	
	
	mov ax, timeCurrent
	lea bx, timeInitial
	add ax, redTime
	add ax, [bx][HFR]
	lea bx, arrivedFlag
	mov cx, [bx][Vertical]
	cmp cx, 0
	je tick_HLR_V_n_arr
	lea bx, timeGainMax
	mov cx, [bx][HFR]
	sub ax, cx
tick_HLR_V_n_arr:
	lea bx, crossingFlag
	mov word ptr [bx + Vertical], 0
	lea bx, crossingTimeLeft
	mov [bx][Vertical], ax
	
	mov ax, timeCurrent
	lea bx, timeInitial
	add ax, redTime
	add ax, [bx][HFR]
	add ax, [bx][HF]
	add ax, [bx][VLR]
	add ax, [bx][VFR]
	mov cx, HLR
	push cx
	call timeGained
	pop cx
	sub ax, cx
	lea bx, arrivedFlag
	mov cx, [bx][Horizontal]
	cmp cx, 0
	je tick_HLR_H_n_arr
	lea bx, timeGainMax
	mov cx, [bx][VLR]
	sub ax, cx
	mov cx, [bx][VFR]
	sub ax, cx
tick_HLR_H_n_arr:
	lea bx, crossingFlag
	mov word ptr [bx + Horizontal], 0
	lea bx, crossingTimeLeft
	mov [bx][Horizontal], ax
	
	ret
tickHLR endp

tickVFR proc near
	sub sp, 2
	call isFinalPhase
	pop cx
	cmp cx, 1 ;if yes
	je tickVFR_isFinal
	xor cx, cx
	mov cl, green
	jmp tickVFR_setSemLight
tickVFR_isFinal:
	mov cx, dx
	mov dx, green

tickVFR_setSemLight:	
	mov di, 2 * (south + right)
	push cx
	push di
	call updateSemaphore
	mov di, 2 * (north + right)
	push cx
	push di
	call updateSemaphore

	mov di, 2 * (south + forward)
	push dx
	push di
	call updateSemaphore
	mov di, 2 * (north + forward)
	push dx
	push di
	call updateSemaphore
	
	
	mov ax, timeCurrent
	lea bx, timeInitial
	add ax, redTime
	
	lea bx, crossingFlag
	mov word ptr [bx + Horizontal], 0
	lea bx, crossingTimeLeft
	mov [bx][Horizontal], ax
	
	mov ax, timeCurrent
	lea bx, timeInitial
	add ax, redTime
	add ax, [bx][VF]
	add ax, [bx][HLR]
	add ax, [bx][HFR]
	mov cx, VFR
	push cx
	call timeGained
	pop cx
	add ax, cx
	mov cx, VLR
	push cx
	call timeGained
	pop cx
	add ax, cx
	lea bx, arrivedFlag
	mov cx, [bx][Vertical]
	cmp cx, 0
	je tick_VFR_V_n_arr
	lea bx, timeGainMax
	mov cx, [bx][HLR]
	sub ax, cx
	mov cx, [bx][HFR]
	sub ax, cx
tick_VFR_V_n_arr:
	lea bx, crossingFlag
	mov word ptr [bx + Vertical], 0
	lea bx, crossingTimeLeft
	mov [bx][Vertical], ax
	
	ret
tickVFR endp

tickHFR proc near
sub sp, 2
	call isFinalPhase
	pop cx
	cmp cx, 1 ;if yes
	je tickHFR_isFinal
	xor cx, cx
	mov cx, green
	jmp tickHFR_setSemLight
tickHFR_isFinal:
	mov cx, dx
	mov dx, green

tickHFR_setSemLight:	
	mov di, 2 * (west + right)
	push cx
	push di
	call updateSemaphore
	mov di, 2 * (east + right)
	push cx
	push di
	call updateSemaphore

	mov di, 2 * (west + forward)
	push dx
	push di
	call updateSemaphore
	mov di, 2 * (east + forward)
	push dx
	push di
	call updateSemaphore
	
	
	mov ax, timeCurrent
	lea bx, timeInitial
	add ax, redTime
	
	lea bx, crossingFlag
	mov word ptr [bx + Vertical], 0
	lea bx, crossingTimeLeft
	mov [bx][Vertical], ax
	
	mov ax, timeCurrent
	lea bx, timeInitial
	add ax, redTime
	add ax, [bx][HF]
	add ax, [bx][VLR]
	add ax, [bx][VFR]
	mov cx, HFR
	push cx
	call timeGained
	pop cx
	add ax, cx
	mov cx, HLR
	push cx
	call timeGained
	pop cx
	add ax, cx
	lea bx, arrivedFlag
	mov cx, [bx][Horizontal]
	cmp cx, 0
	je tick_HFR_H_n_arr
	lea bx, timeGainMax
	mov cx, [bx][VLR]
	sub ax, cx
	mov cx, [bx][VFR]
	sub ax, cx
tick_HFR_H_n_arr:
	lea bx, crossingFlag
	mov word ptr [bx + Horizontal], 0
	lea bx, crossingTimeLeft
	mov [bx][Horizontal], ax
	
	ret
tickHFR endp

tickVF proc	
	sub sp, 2
	call isInitialPhase
	pop cx
	cmp cx, 0
	je tickVF_notInitial
	mov dx, green
tickVF_notInitial:
	mov di, 2 * (south + forward)
	push dx
	push di
	call updateSemaphore
	
	mov di, 2 * (north + forward)
	push dx
	push di
	call updateSemaphore
	
	mov ax, timeCurrent
	sub sp, 2
	call initialTime
	pop cx
	sub cx, redTime
	cmp ax, cx
	jl tickVF_green
	sub ax, cx
	lea bx, crossingFlag
	mov word ptr [bx + Horizontal], 0
	lea bx, crossingTimeLeft
	mov [bx][Horizontal], ax
	jmp tickVF_V
tickVF_green:
	lea bx, crossingFlag
	mov word ptr[bx + Horizontal], 1
	lea bx, crossingTimeLeft
	mov [bx][Horizontal], ax

tickVF_V:
	mov ax, timeCurrent	
	lea bx, timeInitial
	add ax, redTime
	add ax, [bx][HLR]
	add ax, [bx][HFR]
	lea bx, arrivedFlag
	mov cx, [bx][Vertical]
	cmp cx, 0
	je tick_VF_V_n_arr
	lea bx, timeGainMax
	mov cx, [bx][HLR]
	sub ax, cx
	mov cx, [bx][HFR]
	sub ax, cx
tick_VF_V_n_arr:
	lea bx, crossingFlag
	mov word ptr [bx + Vertical], 0
	lea bx, crossingTimeLeft
	mov [bx][Vertical], ax
		
	ret
tickVF endp

tickHF proc	
		
	sub sp, 2
	call isInitialPhase
	pop cx
	cmp cx, 0
	je tickHF_notInitial
	mov dx, green
tickHF_notInitial:
	mov di, 2 * (west + forward)
	push dx
	push di
	call updateSemaphore
	
	mov di, 2 * (east + forward)
	push dx
	push di
	call updateSemaphore
	
	mov ax, timeCurrent
	sub sp, 2
	call initialTime
	pop cx
	sub cx, redTime
	cmp ax, cx
	jl tickHF_green
	sub ax, cx
	lea bx, crossingFlag
	mov word ptr [bx + Vertical], 0
	lea bx, crossingTimeLeft
	mov [bx][Vertical], ax
	jmp tickHF_H
tickHF_green:
	lea bx, crossingFlag
	mov word ptr[bx + Vertical], 1
	lea bx, crossingTimeLeft
	mov [bx][Vertical], ax

tickHF_H:
	mov ax, timeCurrent	
	lea bx, timeInitial
	add ax, redTime
	add ax, [bx][VLR]
	add ax, [bx][VFR]
	lea bx, arrivedFlag
	mov cx, [bx][Horizontal]
	cmp cx, 0
	je tick_HF_H_n_arr
	lea bx, timeGainMax
	mov cx, [bx][VLR]
	sub ax, cx
	mov cx, [bx][VFR]
	sub ax, cx
tick_HF_H_n_arr:
	lea bx, crossingFlag
	mov word ptr [bx + Horizontal], 0
	lea bx, crossingTimeLeft
	mov [bx][Horizontal], ax
		
	ret
tickHF endp

;------------------------------------------------
;	void tick(void)
;------------------------------------------------
tick proc
cli
	push bp
	mov bp, sp
	push	ax
	push	bx
	push	cx
	push	dx
	push	es
	push	ds
	push	si
	push	di
ticky_end:
	mov ax, tickyStart
	mov tickyTick, ax
	
	; determines the light
	sub sp, 2
	call calcLight
	pop dx
	; set light
	; set time for crossing/waiting
tick_light:
	lea bx, timeInitial
	xor ax, ax
	mov al, byte ptr timeMode
	cmp ax, VLR
	je tick_VLR
	cmp ax, VFR
	je tick_VFR
	cmp ax, VF
	je tick_VF
	cmp ax, HLR
	je tick_HLR
	cmp ax, HFR
	je tick_HFR
	cmp ax, HF
	je tick_HF
	; YYY	TODO!

tick_VLR:
	call tickVLR
	jmp tick_update
tick_VFR:
	call tickVFR
	jmp tick_update
tick_VF:	
	call tickVF
	jmp tick_update
tick_HLR:
	call tickHLR
	jmp tick_update
tick_HFR:
	call tickHFR
	jmp tick_update
tick_HF:	
	call tickHF
	jmp tick_update
tick_update:
	
;set colors for display and pedestrian semaphore

	mov ax, Vertical
	push ax
	call calcPedLight
	pop ax
	
	push ax
	mov bx, Vertical
	push bx
	; void updatePedSemaphore(Position, Light)
	call updatePedSemaphore
	
	
	xor dx, dx
	lea bx, crossingTimeLeft
	mov ax, [bx][Vertical]
	xor bx, bx
	mov bx, 100d
	div bx
	xor dx, dx
	mov bx, 10d
	div bx
	push dx
	xor dx, dx
	div bx
	push dx
	
	mov ax, Vertical
	push ax
	call calcPedDispLight
	pop dx
	
	push dx
	mov ax, Vertical
	push ax
	call updatePedDispl
	;
	;
	;

	mov ax, Horizontal
	push ax
	call calcPedLight
	pop ax
	
	push ax
	mov bx, Horizontal
	push bx
	; void updatePedSemaphore(Position, Light)
	call updatePedSemaphore
	
	
	xor dx, dx
	lea bx, crossingTimeLeft
	mov ax, [bx][Horizontal]
	xor bx, bx
	mov bx, 100d
	div bx
	xor dx, dx
	mov bx, 10d
	div bx
	push dx
	xor dx, dx
	div bx
	push dx
	
	mov ax, Horizontal
	push ax
	call calcPedDispLight
	pop dx
	
	push dx
	mov ax, Horizontal
	push ax
	call updatePedDispl	
; update state
	
	mov ax, timeCurrent
	sub ax, timeTick
	cmp ax, 0
	jg tick_noChange
	;	get next timer
	call changeState
	jmp tick_end
	
tick_noChange:
	mov timeCurrent, ax
tick_end:	
	int 60h ; call the old routine
	
	
	pop	di
	pop	si
	pop	ds
	pop	es
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	
	pop bp
	iret
	;ret
tick endp

;----------------------------------------------------
; signature:	Light getSemLight( Semaphore *, Side, Order)
;				>	Semaphore	-	address of the beggining of the semaphore
;				>	Side		-	south, east, north, west (0, 1, 2, 3)
;				>	Order		-	left, foreward, right (0, 1, 2)
; description:	gets the semaphore light
; comment:		the arguments and the return value are passed through the stack;
;				frees the arguments on the stack
; returns:		The light of the semaphore through the stack
getSemLight proc near
	push bp
	mov bp, sp
	
	push ax
	push bx
	push di

	;mov bx, ldArg 0
	getArg bx 0
	getArg di 1
	getArg ax 2
	add di, ax
	mov al, byte ptr[bx+di]
	setArg ax 2
	
	pop di
	pop bx
	pop ax
	pop bp
	ret 4
getSemLight endp
;----------------------------------------------------

;----------------------------------------------------
; signature:	void setSemLight( Semaphore *, Side, Order, Light)
;				>	Semaphore	-	address of the beggining of the semaphore
;				>	Side		-	south, east, north, west (0, 1, 2, 3)
;				>	Order		-	left, foreward, right (0, 1, 2)
;				>	Light		-	light to set
; description:	sets the semaphore light
; comment:		the arguments are passed through the stack;
;				frees the arguments on the stack
setSemLight proc near
	push bp
	mov bp, sp
	
	push ax
	push bx
	push di

	getArg bx 0
	getArg di 1
	getArg ax 2
	add di, ax
	getArg ax 3
	mov byte ptr[bx+di], al
	
	pop di
	pop bx
	pop ax
	pop bp
	ret 8
setSemLight endp
;----------------------------------------------------

;-------------------------------------------
; signature - void initSems(byte* sems)
; description - initializes semaphores
; stack - sems
;-------------------------------------------
initSems proc near
	push bp
	mov bp, sp
	; save locals
	push ax
	push bx
	push cx
	push di
	
	mov al, red
	mov bx, [bp+4]
	mov di, 0
	mov cx, 12
	initSemsLoop:
		mov byte ptr[bx+di], al
		inc di
		loop initSemsLoop
	
	; restore locals
	pop di
	pop cx
	pop bx
	pop ax
	; return
	pop bp
	ret
initSems endp

initTimerRoutine proc near
pushf
	cli
		push es
		push ax

		xor ax, ax  ; inicijalizuje rutinu za tajmer
		mov es,ax

		mov ax, word ptr es:0022h ; pamti staru rutinu
		mov word ptr oldTimerSEG, ax	
		mov ax, word ptr es:0020h	
		mov word ptr oldTimerOFF, ax	

		mov ax, oldTimerSEG	 ;postavlja staru rutinu	
		mov word ptr es:0182h, ax ; na int 60h
		mov ax, oldTimerOFF
		mov word ptr es:0180h, ax

		mov ax, seg tick
		mov word ptr es:0022h, ax	 ;postavlja 
		mov ax, offset tick
		mov word ptr es:0020h, ax ;novu rutinu

		pop ax
		pop es
popf
ret
inittimerRoutine endp

keyboardInt proc 
	push bp
	mov bp, sp
	push ax
	push dx
	push bx
	
	in al, 0060h
	xor ah, ah
	mov dx, ax
	
	in al, 0061h
	or al, 0082h
	out 0061h, al
	and al, 007fh
	out 0061h, al
	mov al, 0020h
	out 0020h, al
	
	lea bx, arrivedFlag
	mov ax, 1
	
	cmp dl, 17; w
	je keyboardIntVer
	cmp dl, 31; s	
	je keyboardIntVer
	cmp dl, 30; a
	je keyboardIntHor
	cmp dl, 32; d	
	je keyboardIntHor
	cmp dl, 1
	jne keyboardIntRet
	
	mov ax, 1
	mov simEnd, ax
	
keyboardIntHor:
	mov [bx][Horizontal], ax
	jmp keyboardIntRet
keyboardIntVer:	
	mov [bx][Vertical], ax
	jmp keyboardIntRet
	

keyboardIntRet:	
	pop bx
	pop dx
	pop ax
	pop bp
	iret
keyboardInt endp

setKeyboardInt proc near
	pushf
	cli
	
	push ax
	push es
	
	mov ax, 0000h					; inicijalizacija ES registra sa pocetnom adresom IVT-a
	mov es, ax					
	mov ax, es:[09h*4]				;offset adrese stare prekidne rutine se cuva u promenjivoj oldTimerIR
	mov word ptr oldKeyOFF, ax		
	mov ax, es:[09h*4 + 2]				; segment adrese stare prekidne rutine se cuva u sledecoj reci iza mesta u memoriji gde je sacuvan offset
	mov word ptr oldKeySEG, ax

	;cli	;onemogucavaju se prekidi jer se snima u IVT
	mov word ptr es:[09h*4], offset keyboardInt	;snimanje offseta IVT
	mov word ptr es:[09h*4 + 2], seg keyboardInt	;snimanje segmenta IVT
	;sti	;ponovo su omoguceni prekidi

	pop es
	pop ax
	popf
	ret
setKeyboardInt endp

restoreInt proc near
pushf
	cli
		push es
		push ax

		xor ax, ax  ; inicijalizuje rutinu za tastaturu
		mov es,ax

		mov ax, oldTimerSEG
		mov word ptr es:0022h, ax	 ;postavlja 
		mov ax, oldTimerOFF
		mov word ptr es:0020h, ax ;novu rutinu	

		mov ax, oldKeySEG
		mov word ptr es:0026h, ax	 ;postavlja 
		mov ax, oldKeyOFF
		mov word ptr es:0024h, ax ;novu rutinu

		pop ax
		pop es
popf
ret
restoreInt endp

;////////////////////////////////////////////////////////////
;	main program
;////////////////////////////////////////////////////////////
main proc

	; initialize ds
	mov ax, @DATA
	mov ds, ax

	; initialize semapfores
	lea ax, semaphores
	push ax
	call initSems
	pop ax
	
	call drawCrossRoad
	
	mov     ax, 1003h
	mov     bx, 0      ; disable blinking.
	int     10h
	
	call setKeyboardInt
	
	call initTimerRoutine
	; mov dx, yellow
	; mov di, 2 * (north + right)
	; push dx
	; push di
	; call updateSemaphore
	sti
here: 
	pushf
	cli
	mov ax, simEnd
	popf
	cmp ax, 0
	je here
	
	call restoreInt
	
	xor ax, ax
	mov ax,04C00h 	; return to DOS
	int 21h
main endp
;////////////////////////////////////////////////////////////

end main	;MAIN - entry point
